package com.mindskip.xzs.controller.admin;
//用于处理文件上传请求，特别是图片上传请求，以及对前端提供UEditor配置。控制器类名为`UploadController`，继承自`BaseApiController`。
//文件上传
//URL: `/api/admin/upload/configAndUpload`
//当前端需要上传文件（例如图片）时，会向这个URL发送`POST`请求，并附带文件数据。
//前端应使用`multipart/form-data`编码类型来发送包含文件的请求。
//上传成功后，前端会收到包含文件信息（如URL、文件名、文件大小等）的响应数据，可以用来显示上传的图片或进行其他操作。

//获取UEditor配置
//URL: `/api/admin/upload/configAndUpload`
//当前端需要获取UEditor（一个流行的富文本编辑器）的配置时，会向这个URL发送`GET`请求。
//前端会收到一个JSON对象，包含UEditor的相关配置，如允许的图片格式、最大图片大小等，用于初始化编辑器。

//更新用户头像
//URL: `/api/admin/upload/image`
//当前端需要为用户上传并更新头像时，会向这个URL发送`POST`请求，并附带文件数据。
//上传成功后，前端会收到新的头像URL，可以用来更新用户的头像显示。
//文件上传处理
//在`/configAndUpload`方法中，当请求的`action`参数等于`"imgUpload"`时，处理文件上传。
//使用`MultipartHttpServletRequest`来处理上传的文件，并获取文件信息（如文件名、文件大小、输入流等）。
//调用`fileUpload`服务的`uploadFile`方法，将文件上传到指定位置，并返回文件路径。
//创建并返回`UploadResultVM`对象，包含文件上传的详细信息。
//UEditor配置返回：
//在`/configAndUpload`方法中，当请求的`action`参数不等于`"imgUpload"`时，返回UEditor的配置。
//创建并返回`UeditorConfigVM`对象，包含UEditor的配置，如允许的图片格式、最大图片大小等。
//用户头像上传和更新：
//在`/image`方法中，处理用户头像的上传。
//使用`MultipartHttpServletRequest`来处理上传的文件，并获取文件信息。
//调用`fileUpload`服务的`uploadFile`方法，将文件上传到指定位置，并返回文件路径。
//调用`userService`服务的`changePicture`方法，更新当前用户的头像URL。
//返回包含文件路径的`RestResponse`对象，表示操作成功或失败。

import com.mindskip.xzs.base.BaseApiController;
import com.mindskip.xzs.base.RestResponse;
import com.mindskip.xzs.configuration.property.SystemConfig;
import com.mindskip.xzs.service.FileUpload;
import com.mindskip.xzs.service.UserService;
import com.mindskip.xzs.viewmodel.admin.file.UeditorConfigVM;
import com.mindskip.xzs.viewmodel.admin.file.UploadResultVM;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;

@RequestMapping("/api/admin/upload")
@RestController("AdminUploadController")
public class UploadController extends BaseApiController {

    // 文件上传服务
    private final FileUpload fileUpload;
    // 系统配置
    private final SystemConfig systemConfig;
    // 日志记录器
    private static final Logger logger = LoggerFactory.getLogger(UploadController.class);
    // 图片上传动作名称
    private static final String IMAGE_UPLOAD = "imgUpload";
    // 图片上传文件字段名
    private static final String IMAGE_UPLOAD_FILE = "upFile";
    // 用户服务
    private final UserService userService;

    // 使用@Autowired注解自动注入需要的服务
    @Autowired
    public UploadController(FileUpload fileUpload, SystemConfig systemConfig, UserService userService) {
        this.fileUpload = fileUpload;
        this.systemConfig = systemConfig;
        this.userService = userService;
    }

    // 处理文件上传和配置请求
    @ResponseBody
    @RequestMapping("/configAndUpload")
    public Object upload(HttpServletRequest request, HttpServletResponse response) {
        // 获取请求中的action参数
        String action = request.getParameter("action");
        // 如果action是图片上传
        if (action.equals(IMAGE_UPLOAD)) {
            try {
                // 将HttpServletRequest转换为MultipartHttpServletRequest，以便处理文件上传
                MultipartHttpServletRequest multipartHttpServletRequest = (MultipartHttpServletRequest) request;
                // 获取上传的文件
                MultipartFile multipartFile = multipartHttpServletRequest.getFile(IMAGE_UPLOAD_FILE);
                // 获取文件大小
                long attachSize = multipartFile.getSize();
                // 获取文件的原始名称
                String imgName = multipartFile.getOriginalFilename();
                String filePath;
                // 使用try-with-resources语句确保InputStream在使用后关闭
                try (InputStream inputStream = multipartFile.getInputStream()) {
                    // 上传文件，并获取文件路径
                    filePath = fileUpload.uploadFile(inputStream, attachSize, imgName);
                }
                // 获取文件类型（扩展名）
                String imageType = imgName.substring(imgName.lastIndexOf("."));
                // 创建上传结果的视图模型
                UploadResultVM uploadResultVM = new UploadResultVM();
                uploadResultVM.setOriginal(imgName);
                uploadResultVM.setName(imgName);
                uploadResultVM.setUrl(filePath);
                uploadResultVM.setSize(multipartFile.getSize());
                uploadResultVM.setType(imageType);
                uploadResultVM.setState("SUCCESS");
                return uploadResultVM;
            } catch (IOException e) {
                // 记录异常信息
                logger.error(e.getMessage(), e);
            }
        } else {
            // 如果action不是图片上传，返回UEditor配置
            UeditorConfigVM ueditorConfigVM = new UeditorConfigVM();
            ueditorConfigVM.setImageActionName(IMAGE_UPLOAD);
            ueditorConfigVM.setImageFieldName(IMAGE_UPLOAD_FILE);
            ueditorConfigVM.setImageMaxSize(2048000L); // 最大图片大小，单位为字节
            ueditorConfigVM.setImageAllowFiles(Arrays.asList(".png", ".jpg", ".jpeg", ".gif", ".bmp")); // 允许的图片格式
            ueditorConfigVM.setImageCompressEnable(true); // 是否启用图片压缩
            ueditorConfigVM.setImageCompressBorder(1600); // 图片压缩边界
            ueditorConfigVM.setImageInsertAlign("none"); // 图片插入对齐方式
            ueditorConfigVM.setImageUrlPrefix(""); // 图片URL前缀
            ueditorConfigVM.setImagePathFormat(""); // 图片路径格式
            return ueditorConfigVM;
        }
        return null;
    }

    // 处理图片上传及Excel读取的请求
    @RequestMapping("/image")
    @ResponseBody
    public RestResponse questionUploadAndReadExcel(HttpServletRequest request) {
        // 将HttpServletRequest转换为MultipartHttpServletRequest，以便处理文件上传
        MultipartHttpServletRequest multipartHttpServletRequest = (MultipartHttpServletRequest) request;
        // 获取上传的文件
        MultipartFile multipartFile = multipartHttpServletRequest.getFile("file");
        // 获取文件大小
        long attachSize = multipartFile.getSize();
        // 获取文件的原始名称
        String imgName = multipartFile.getOriginalFilename();
        try (InputStream inputStream = multipartFile.getInputStream()) {
            // 上传文件，并获取文件路径
            String filePath = fileUpload.uploadFile(inputStream, attachSize, imgName);
            // 更新当前用户的头像
            userService.changePicture(getCurrentUser(), filePath);
            return RestResponse.ok(filePath);
        } catch (IOException e) {
            // 返回错误响应
            return RestResponse.fail(2, e.getMessage());
        }
    }
}
